#include "comm.hpp"

// 直接通过共享内存通信
void server1()
{
    key_t key = GetKey();
    cout << "key: " << ToHex(key) << endl;

    int shmid = CreateShm(key);
    cout << "共享内存id: " << shmid << endl;
    sleep(5);
    // 挂接到共享内存
    char *str = (char *)shmat(shmid, nullptr, 0);

    // 实现通信
    cout << "开始进行通信" << endl;
    while (1)
    {
        sleep(1);
        cout << "挂接到共享内存的内容：" << str << endl;
    }
    // 共享内存通信，不是 同步 通信的，直接裸露给所以使用者，需要考虑使用安全问题
    // 会导致数据流无法同步，使得接受端、发送端的信息不一致

    shmdt(str);
    cout << "将shm从进程地址空间中移除……" << endl;

    sleep(5);
    shmctl(shmid, IPC_RMID, nullptr);
}

// 通过共享内存和命名管道进行通信
void server2()
{
    // 创建管道文件fifo，权限0666
    mkfifo("fifo", 0666);
    key_t key = GetKey();
    cout << "key: " << ToHex(key) << endl;

    int shmid = CreateShm(key);
    cout << "共享内存id: " << shmid << endl;
    sleep(5);

    char *str = (char *)shmat(shmid, nullptr, 0);

    // 通过只读方式接收信息
    int r_open = open("fifo", O_RDONLY);

    // 实现通信
    cout << "开始进行通信" << endl;
    while (1)
    {
        read(r_open, str, sizeof(str));
        cout << "挂接到共享内存的内容：" << str << endl;
        sleep(1);
    }

    shmdt(str);
    cout << "将shm从进程地址空间中移除……" << endl;

    sleep(5);
    close(r_open);
    shmctl(shmid, IPC_RMID, nullptr);
}
void test()
{
    key_t key = GetKey();
    cout << "key: " << ToHex(key) << endl;
    int shmid = CreateShm(key);

    struct shmid_ds ds;
    // 通过IPC_STAT将该shmid中维护的结构体数据加载进ds中
    shmctl(shmid, IPC_STAT, &ds);

    cout << ds.shm_perm.__key << endl;
    cout << ToHex(ds.shm_perm.__key) << endl;
    cout << ds.shm_nattch << endl;

    sleep(5);
    shmctl(shmid, IPC_RMID, nullptr);
}
int main()
{
    test();
}